/**
 ******************************************************************************
 * @file    bsp_adc_potentiometer.c
 * @author  fire
 * @version V1.0
 * @date    2024-xx-xx
 * @brief   ADC应用函数接口
 ******************************************************************************
 * @attention
 *
 * 实验平台:野火 F103 STM32 开发板
 * 论坛    :http://www.firebbs.cn
 * 淘宝    :https://fire-stm32.taobao.com
 *
 ******************************************************************************
 */
#include "adc/bsp_adc_potentiometer.h"
#include "bsp_usart.h"

ADC_InitTypeDef ADC_InitStructure;

uint8_t potentiometer_flag = 0;           //电位器标志位
uint16_t potentiometer_task_time;         //电位器任务计时计数值

/**
 * @brief  电位器GPIO配置
 * @param  无
 * @retval 无
 */
static void Potentiometer_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    
    /* 开启ADC相关的GPIO外设时钟 */
    ADCX_IN_APBXCLOCK_FUN(ADCX_IN_GPIO_CLK,ENABLE);
    /* 选择要控制的GPIO引脚 */
    GPIO_InitStruct.GPIO_Pin = ADCX_IN_GPIO_PIN;
    /* 设置引脚的输出类型为模拟输入 */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
    /* 设置引脚速率为高速 */
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    /* 调用库函数，使用上面配置的GPIO_InitStructure初始化GPIO */
    GPIO_Init(ADCX_IN_GPIO_PORT, &GPIO_InitStruct);
}

/**
 * @brief  电位器ADC配置
 * @param  无
 * @retval 无
 */
static void Potentiometer_ADC_Config(void)
{

    
    /* 开启ADC外设时钟 */
    ADCX_APBXCLOCK_FUN(ADCX_CLK,ENABLE);

	// ADC 模式配置
	// 只使用一个ADC，属于单模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	
	// 扫描模式
	ADC_InitStructure.ADC_ScanConvMode = ENABLE ; 

	// 连续转换模式
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

	// 不用外部触发转换，软件开启即可
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

	// 转换结果右对齐
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	
	// 转换通道个数
	ADC_InitStructure.ADC_NbrOfChannel = 1;	
		
	// 初始化ADC
	ADC_Init(ADCX, &ADC_InitStructure);
	
	// 配置ADC时钟PCLK2的8分频，即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	
	// 配置ADC 通道的转换顺序和采样时间
	ADC_RegularChannelConfig(ADCX, ADCX_CHANNEL, 1, ADC_SampleTime_55Cycles5);
		
	// 开启ADC ，并开始转换
	ADC_Cmd(ADCX, ENABLE);
	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADCX);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADCX));
	
	// ADC开始校准
	ADC_StartCalibration(ADCX);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADCX));
	
	// 由于没有采用外部触发，所以使用软件触发ADC转换 
	ADC_SoftwareStartConvCmd(ADCX, ENABLE);
}

/**
 * @brief  电位器初始化
 * @param  无
 * @retval 无
 */
void Potentiometer_ADC_Init(void)
{
    Potentiometer_GPIO_Config();
    Potentiometer_ADC_Config();

}

/**
 * @brief  电位器ADC采集任务
 * @param  无
 * @retval 无
 */
void Potentiometer_ADC_Task(void)
{
    /* 检查电位器标志位 */  
    if(potentiometer_flag)      
    {
        /* 判断转换完成标志位是否置1 即转换是否完成 */
        if (ADC_GetFlagStatus(ADCX, ADC_FLAG_EOC) == 1)
        {
            printf("\r\nThe current voltage = %0.2f V\r\n", (float)ADC_GetConversionValue(ADCX) / 4096 * 3.3);
            printf("\r\nThe current AD value = %d\r\n", ADC_GetConversionValue(ADCX));
        }  
        /* 清除电位器标志位 */    
        potentiometer_flag = 0;
    }
}
